package com.bigger.arch.app.biz.impl;

import com.bigger.arch.app.biz.IUserBiz;
import com.bigger.arch.app.repository.dao.UserDao;
import com.bigger.arch.app.repository.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.List;

@Service
public class UserBizImpl implements IUserBiz {
    @Autowired
    @Qualifier("MyUserDaoImpl")
    private UserDao userDao;

    public Boolean saveItem(UserModel userModel) {
        if (userModel == null) {
            return false;
        }

        userModel.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        userModel.setIsDelete(false);

        if (userModel.getId() == null || userModel.getId() <= 0) {
            userModel.setCreateTime(new Timestamp(System.currentTimeMillis()));
            return userDao.insertItem(userModel) > 0;
        }

        UserModel userModelDB = userDao.getItemById(userModel.getId());
        if (userModelDB == null) {
            return false;
        }
        userModel.setCreateTime(userModelDB.getCreateTime());
        return userDao.updateItem(userModel) > 0;
    }

    public UserModel getItem(Integer id) {
        return userDao.getItemById(id);
    }

    public List<UserModel> getItems() {
        return userDao.getItems();
    }

    public BigInteger getCount() {
        return userDao.getCount();
    }

    @Autowired
    //@Qualifier("tran_db_test")
    public DataSourceTransactionManager transactionManager;

    public Boolean transferAccount(String fromName, String toName, BigDecimal balance) {
        UserModel fromUser = userDao.getItemByName(fromName);
        if (fromUser == null) {
            return false;
        }
        if (fromUser.getBalance().compareTo(balance) < 0) {
            return false;
        }
        UserModel toUser = userDao.getItemByName(toName);
        if (toUser == null) {
            return false;
        }

        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus transactionStatus = transactionManager.getTransaction(definition);

        try {
            fromUser.setBalance(fromUser.getBalance().subtract(balance));
            Integer reusult = userDao.updateBalance(fromUser);
            if (reusult <= 0) {
                return false;
            }

            //事务回滚测试
            //int mathResult = 10 / 0;

            toUser.setBalance(toUser.getBalance().add(balance));
            reusult = userDao.updateBalance(toUser);
            if (reusult <= 0) {
                return false;
            }
            transactionManager.commit(transactionStatus);
            return true;
        } catch (Exception exception) {
            transactionManager.rollback(transactionStatus);
            //todo:记录日志
            return false;
        }
    }

    /*@Transactional
    public Boolean transferAccount(String fromName, String toName, BigDecimal balance) {
        UserModel fromUser = userDao.getItemByName(fromName);
        if (fromUser == null) {
            return false;
        }
        if (fromUser.getBalance().compareTo(balance) < 0) {
            return false;
        }
        UserModel toUser = userDao.getItemByName(toName);
        if (toUser == null) {
            return false;
        }


        try {
            fromUser.setBalance(fromUser.getBalance().subtract(balance));
            Integer reusult = userDao.updateBalance(fromUser);
            if (reusult <= 0) {
                return false;
            }

            //事务回滚测试
            int mathResult = 10 / 0;

            toUser.setBalance(toUser.getBalance().add(balance));
            reusult = userDao.updateBalance(toUser);
            if (reusult <= 0) {
                return false;
            }
            return true;
        } catch (Exception exception) {
            //todo:记录日志
            //这种方式会抛异常，个人推荐使用上面的方式回滚
            throw new RuntimeException(exception);
        }
    }*/
}
